package ;
import easelhx.display.BitmapAnimation;
import easelhx.display.Graphics;
import easelhx.display.Shape;
import easelhx.display.SpriteSheet;
import easelhx.display.Text;
import easelhx.events.MouseEvent;
import easelhx.js.Image;
import easelhx.utils.Ticker;
import js.Lib;

/**
 * ...
 * @author 
 */

class SparklesExample extends Example
{
	private var imgSeq:Image;
	private var bmpAnim:BitmapAnimation;	// The animated sparkle template to clone
	private var fpsLabel:Text;

	public function new() 
	{
		super();
	}
	
	override public function run():Void 
	{
		super.run();
		
		imgSeq = new Image();		// The image for the sparkle animation
		
		// attach mouse handlers directly to the source canvas.
		// better than calling from canvas tag for cross browser compatibility:
		stage.onMouseMove = moveCanvas;
		stage.onMouseDown = clickCanvas;
		
		var bkg:Shape = new Shape(new Graphics());
		bkg.graphics.beginFill("#666666");
		bkg.graphics.drawRect(0, 0, canvas.width, canvas.height);
		stage.addChild(bkg);
		
		// define simple sprite sheet data specifying the image(s) to use, the size of the frames,
		// and the registration point of the frame
		// it will auto-calculate the number of frames from the image dimensions and loop them
		var data = {
			images: ["assets/sparkle_21x23.png"],
			frames: { width:21, height:23, regX:10, regY:11 }
		}
		
		// set up an animation instance, which we will clone
		bmpAnim = new BitmapAnimation(new SpriteSheet(data));

		// add a text object to output the current FPS:
		fpsLabel = new Text("-- fps", "bold 14px Arial", "#FFFFFF");
		stage.addChild(fpsLabel);
		fpsLabel.x = 10;
		fpsLabel.y = 20;
		
		// start the tick and point it at the window so we can do some work before updating the stage:
		Ticker.setFPS(20);
		Ticker.addListener(this);
	}
	
	private function tick() : Void
	{
		// loop through all of the active sparkles on stage:
		var l = stage.getNumChildren();
		//for (var i = l - 1; i > 0; i--) {
		var i:Int = l - 1;
		while (i > 1) {
			var sparkle = stage.getChildAt(i);

			// apply gravity and friction
			untyped sparkle.vY += 2;
			untyped sparkle.vX *= 0.98;

			// update position, scale, and alpha:
			untyped sparkle.x += sparkle.vX;
			untyped sparkle.y += sparkle.vY;
			untyped sparkle.scaleX = sparkle.scaleY = sparkle.scaleX+sparkle.vS;
			untyped sparkle.alpha += sparkle.vA;

			//remove sparkles that are off screen or not invisble
			if (sparkle.alpha <= 0 || sparkle.y > canvas.height) {
				stage.removeChildAt(i);
			}
			i--;
		}

		fpsLabel.text = Math.round(Ticker.getMeasuredFPS())+" fps";

		// draw the updates to stage
		stage.update();
	}

	//sparkle explosion
	private function clickCanvas(evt:MouseEvent) : MouseEvent
	{
		addSparkles(Std.int(Math.random() * 200 + 100) | 0, stage.mouseX, stage.mouseY, 2);
		return evt;
	}

	//sparkle trail
	private function moveCanvas(evt:MouseEvent) : MouseEvent
	{
		addSparkles(Std.int(Math.random() * 2 + 1) | 0, stage.mouseX, stage.mouseY, 1);
		return evt;
	}

	private function addSparkles(count:Int, x:Float, y:Float, speed:Float) : Void
	{
		//create the specified number of sparkles
		for (i in 0...count) {
			// clone the original sparkle, so we don't need to set shared properties:
			var sparkle:BitmapAnimation = cast bmpAnim.clone();

			// set display properties:
			sparkle.x = x;
			sparkle.y = y;
			//sparkle.rotation = Math.random()*360;
			sparkle.alpha = Math.random()*0.5+0.5;
			sparkle.scaleX = sparkle.scaleY = Math.random()+0.3;
		
			// set up velocities:
			var a = Math.PI * 2 * Math.random();
			var v = (Math.random() - 0.5) * 30 * speed;
			
			Reflect.setProperty( sparkle, "vX", Math.cos(a) * v);
			Reflect.setProperty( sparkle, "vY", Math.sin(a) * v);
			Reflect.setProperty( sparkle, "vS",  (Math.random() - 0.5) * 0.2); // scale
			Reflect.setProperty( sparkle, "vA",  -Math.random() * 0.05 - 0.01); // alpha
			
			// start the animation on a random frame:
			sparkle.gotoAndPlay(Std.int(Math.random() * sparkle.spriteSheet.getNumFrames()) | 0);

			// add to the display list:
			stage.addChild(sparkle);
		}
	}
	
}